package com.woniu.park.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;

import com.woniu.park.component.DBRealm;
import com.woniu.park.util.EncryptUtil;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @version: V1.0
 * @author: 陈小宝
 * @className: Config
 * @packageName: com.woniu.cq.config
 * @description:
 * @data: 2020-09-02 19:08
 */
//@EnableTransactionManagement
@Configuration
@MapperScan("com.woniu.all.dao")
public class Config {

//    @Bean
//    public CacheManager cacheManager(){
//        return new MemoryConstrainedCacheManager();
//    }

    //Shiro
    @Bean
    public Realm realm() {
        DBRealm dbRealm = new DBRealm();
        //设置到realm中
        dbRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return dbRealm;
    }

    //将hash码验证器注入
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        //用户输入的密码    数据库中的正确密码
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置算法名字
        hashedCredentialsMatcher.setHashAlgorithmName(EncryptUtil.ALGORITHM_NAME);
        //设置hash迭代次数
        hashedCredentialsMatcher.setHashIterations(EncryptUtil.HASH_ITERATIONS);
        return hashedCredentialsMatcher;
    }

    //Shiro过滤器链配置
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition dsfcd = new DefaultShiroFilterChainDefinition();
        //xxx路径->某个过滤器
        //public enum DefaultFilter

        //不拦截 anon
        //需要登录 user
        //登出 logout

        //不拦截
        dsfcd.addPathDefinition("/css/**","anon");
        dsfcd.addPathDefinition("/js/**","anon");
        dsfcd.addPathDefinition("/images/**","anon");
        dsfcd.addPathDefinition("/html/**","anon");
        dsfcd.addPathDefinition("/fonts/**","anon");
        dsfcd.addPathDefinition("/layui/**","anon");
        dsfcd.addPathDefinition("/","anon");
        dsfcd.addPathDefinition("/login.html","anon");
        dsfcd.addPathDefinition("/login","anon");
        dsfcd.addPathDefinition("/top.html","anon");
        dsfcd.addPathDefinition("/main.html","anon");
        dsfcd.addPathDefinition("/index.html","anon");
        dsfcd.addPathDefinition("/register.html","anon");
        dsfcd.addPathDefinition("/register","anon");
        dsfcd.addPathDefinition("/queryHistory","anon");
        //测试时不拦截
//        dsfcd.addPathDefinition("/contract.html","anon");
//        dsfcd.addPathDefinition("/lessor.html","anon");
//        dsfcd.addPathDefinition("/property.html","anon");
//        dsfcd.addPathDefinition("/tenant.html","anon");
//        dsfcd.addPathDefinition("/findPark","anon");
//        dsfcd.addPathDefinition("/test.html","anon");
//        dsfcd.addPathDefinition("/commentTest.html","anon");
//        dsfcd.addPathDefinition("/order/show","anon");
//        dsfcd.addPathDefinition("/show.html","anon");
//        dsfcd.addPathDefinition("/test.html","anon");
//        dsfcd.addPathDefinition("/pay.html","anon");
//        dsfcd.addPathDefinition("/findPark","anon");
//        dsfcd.addPathDefinition("/insertPark","anon");
//        dsfcd.addPathDefinition("/checkPark","anon");
        dsfcd.addPathDefinition("/code","anon");
//        dsfcd.addPathDefinition("/booking","anon");
//        dsfcd.addPathDefinition("/dc","anon");
//        dsfcd.addPathDefinition("/historyOrder","anon");
//        dsfcd.addPathDefinition("/comment","anon");
//        dsfcd.addPathDefinition("/getComment","anon");
//        dsfcd.addPathDefinition("/reply","anon");
//        dsfcd.addPathDefinition("/cancellation","anon");
//        dsfcd.addPathDefinition("/queryHistory","anon");
//        dsfcd.addPathDefinition("/Park","anon");
//        dsfcd.addPathDefinition("/payMoney","anon");
        dsfcd.addPathDefinition("/updateTransfer","anon");
//        dsfcd.addPathDefinition("/send","anon");
//        dsfcd.addPathDefinition("/change","anon");
        dsfcd.addPathDefinition("/message","anon");
//        dsfcd.addPathDefinition("/dx","anon");
//        dsfcd.addPathDefinition("/query","anon");
//        dsfcd.addPathDefinition("/back","anon");

        //登出
        dsfcd.addPathDefinition("/logout","logout");
        //拦截
        dsfcd.addPathDefinition("/**","user");

        return dsfcd;

    }

    //解决权限注解与RequestMapping冲突
    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        /**
         * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。
         * 在@Controller注解的类的方法中加入@RequiresRole等shiro注解，会导致该方法无法映射请求，导致返回404。
         * 加入这项配置能解决这个bug
         */
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
        return defaultAdvisorAutoProxyCreator;
    }

    //分页插件
    //使用时controller层用IPage<>接收 Service层中用Page类和turtorMapper.queryTurtorPage(page,条件)获取IPage;
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作， true调回到首页，false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量，默认 500 条，-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }

}
